package com.ty.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ty.entity.*;
import com.ty.mapper.*;
import com.ty.req.OrderReq;
import com.ty.resp.CommonResp;
import com.ty.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ty.utils.OrderCodeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author txy
 * @since 2024-03-02
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
    @Resource
    private BookMapper periodicalMapper;
    @Resource
    private CartsMapper cartsMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private UserMapper userMapper;

    @Override
    public CommonResp getOrders(Page page, String name, String userId, Integer status) {
        CommonResp resp = new CommonResp();
        QueryWrapper<Orders> wrapper = new QueryWrapper();
        wrapper.apply("o.order_id = oi.order_id and oi.periodical_id = p.id");
        if (status != null && status > 0 && status < 9) {
            wrapper.eq("o.order_status", status);
        } else {
            wrapper.between("o.order_status", -1, 6);
        }
        if (StringUtils.hasText(userId)) {
            wrapper.eq("o.user_id", userId);
        }
        if (StringUtils.hasText(name)) {
            //使用and，将后续的条件括起来，保证条件执行顺序
            wrapper.and(item -> item.like("p.name", name).or().like("o.order_id", name));
        }
        Page page1 = baseMapper.selectAllOrder(page, wrapper);
        resp.setContent(page1.getRecords());
        resp.setTotal(page1.getTotal());
        return resp;
    }

    @Transactional(rollbackFor = Exception.class, isolation = Isolation.SERIALIZABLE)
    @Override
    public synchronized CommonResp createOrder(OrderReq orderReq) {
        String orderCode = OrderCodeUtil.getOrderCode((long) (Math.random() * 100));//生成订单id
        AtomicReference<Double> shouldPay = new AtomicReference<>(0.0);
        AtomicInteger insert = new AtomicInteger();
        UpdateWrapper wrapper1 = new UpdateWrapper();
        CommonResp resp = new CommonResp();
        //判断是否传递商品id
        if (StringUtils.hasText(orderReq.getIds())) {
            if (orderReq.getIds().contains(",")) {//购物车
                String[] ids = orderReq.getIds().split(",");
                QueryWrapper<Carts> wrapper = new QueryWrapper<>();
                wrapper.in("periodical_id", ids);
                wrapper.eq("user_id", orderReq.getUserId());
                List<Carts> carts = cartsMapper.selectCart(wrapper);
                //判断库存是否充足
                for (int i = 0; i < carts.size() - 1; i++) {//前端传递的ids会以，结尾，所以去掉空的最后一个
                    //有库存就添加到订单
                    if (haveInventory(carts.get(i).getPeriodicalId(), carts.get(i).getNum())) {
                        carts.forEach(x -> {
                            OrderItem orderItem = new OrderItem(x.getPeriodicalId(), orderCode, x.getNum(),
                                    x.getYear(), x.getStartTime(), x.getPeriodical().getPrice());
                            shouldPay.updateAndGet(v -> v + x.getNum() * x.getPeriodical().getPrice());
                            insert.set(orderItemMapper.insert(orderItem));
                            if (insert.get() > 0) {
                                wrapper1.setSql("num = num - " + x.getNum() + ", sales_num = sales_num + " + x.getNum());
                                wrapper1.eq("id", x.getPeriodicalId());
                                periodicalMapper.update(wrapper1);
                                cartsMapper.deleteById(x);
                            }
                        });
                    } else {
                        //手工回滚异常
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        resp.setSuccess(false);
                        resp.setMessage("可能是其中某一个商品库存不足，请管理员补货后重试！");
                        return resp;
                    }
                }
            } else {//自选
                if (haveInventory(orderReq.getIds(), orderReq.getNum())) {
                    OrderItem orderItem = new OrderItem(orderReq.getIds(), orderCode, orderReq.getNum(),
                            orderReq.getYear(), orderReq.getStartTime(), orderReq.getPrice());
                    shouldPay.updateAndGet(v -> v + orderReq.getNum() * orderReq.getYear() * orderReq.getPrice());
                    insert.set(orderItemMapper.insert(orderItem));
                    wrapper1.setSql("num = num - " + orderReq.getNum() + ", sales_num = sales_num + " + orderReq.getNum());
                    wrapper1.eq("id", orderReq.getIds());
                    periodicalMapper.update(wrapper1);
                } else {
                    //手工回滚异常
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    resp.setSuccess(false);
                    resp.setMessage("商品库存不足，请管理员补货后重试！");
                    return resp;
                }
            }
            if (insert.get() > 0) {//是否插入成功
                Orders orders = new Orders();
                orders.setOrderId(orderCode);//订单id
                DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                orders.setCreateTime(LocalDateTime.parse(sdf.format(new Date()), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));//创建时间
                orders.setAddrId(orderReq.getAddressId());//收货地址id
                orders.setOrderStatus(1);//订单支付状态，1：未支付
                orders.setUserId(orderReq.getUserId());//用户id
                orders.setShouldPay(String.valueOf(shouldPay.get()));//应付金额
                insert.set(baseMapper.insert(orders));
            }
            resp.setSuccess(insert.get() > 0);
            resp.setContent(orderCode);
        } else {
            resp.setSuccess(false);
            resp.setMessage("没有传递购买的图书id");
        }
        return resp;
    }

    public Boolean haveInventory(String id, Integer num) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("id", id);
        wrapper.gt("num", num);
        List list = periodicalMapper.selectList(wrapper);
        return !list.isEmpty();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommonResp updateOrder(String orderId, Integer paymentType, String userId, Integer status) {
        CommonResp resp = new CommonResp();
        if (StringUtils.hasText(orderId) && StringUtils.hasText(userId)) {
            UpdateWrapper<Orders> wrapper = new UpdateWrapper<>();
            wrapper.eq("order_id", orderId);
            wrapper.eq("user_id", userId);
            if (status == 4) {//确认收货，将用户的消费金额加上该订单的金额
                //查找对应的订单
                QueryWrapper<Orders> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("order_id", orderId);
                queryWrapper.eq("user_id", userId);
                Orders orders = baseMapper.selectOne(queryWrapper);
                //更新用户表
                UpdateWrapper wrapper1 = new UpdateWrapper();
                wrapper1.eq("id", orders.getUserId());
                wrapper1.set("total", orders.getPayment());
                userMapper.update(wrapper1);
            }
            /**
             * 状态：1、未付款，2、已付款,未发货，3、已发货，4、交易成功，5、交易关闭 ,6、退款中，7、退款成功,8、退款失败
             */
            if (status != null && status > 0 && status < 9) {
                wrapper.set("order_status", status);
            }

            if (status == 5 || status == 7) {//取消订单或者退款成功，将减去的数量加回来
                //查询该订单的商品购买数量
                QueryWrapper<OrderItem> wrapper1 = new QueryWrapper<>();
                wrapper1.eq("order_id", orderId);
                List<OrderItem> list = orderItemMapper.selectList(wrapper1);
                //将数量加回数据库
                list.forEach(x -> {
                    UpdateWrapper<Book> periodicalEntityUpdateWrapper = new UpdateWrapper<>();
                    periodicalEntityUpdateWrapper.setSql("num = num + " + x.getNum());
                    periodicalEntityUpdateWrapper.setSql("sales_num = sales_num - " + x.getNum());
                    periodicalEntityUpdateWrapper.eq("id", x.getPeriodicalId());
                    periodicalMapper.update(periodicalEntityUpdateWrapper);
                });
            }

            if (status == 2) {//说明是付款，有付款时间
                wrapper.set("payment_type", paymentType);
                wrapper.setSql("payment = should_pay");
                DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                wrapper.set("payment_time", sdf.format(new Date()));
            }
            int update = baseMapper.update(wrapper);
            resp.setSuccess(update > 0);
        } else {
            resp.setSuccess(false);
            resp.setMessage("订单id或者用户id为空");
        }
        return resp;

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommonResp deleteOrder(String orderId, String userId) {
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("order_id", orderId);
        orderItemMapper.delete(wrapper);
        wrapper.eq("user_id", userId);
        int delete = baseMapper.delete(wrapper);
        CommonResp resp = new CommonResp();
        resp.setSuccess(delete > 0);
        return resp;
    }

    @Override
    public CommonResp shipmentsOrder(Orders order) {
        UpdateWrapper wrapper = new UpdateWrapper();
        //发货设置属性
        wrapper.set("shipping_name", order.getShippingName());
        wrapper.set("shipping_code", OrderCodeUtil.getOrderCode((long) (Math.random() * 1000)));
        wrapper.set("order_status", 3);
        wrapper.eq("order_id", order.getOrderId());
        wrapper.eq("user_id", order.getUserId());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        wrapper.set("consign_time", dateFormat.format(new Date()));
        CommonResp resp = new CommonResp();
        resp.setSuccess(baseMapper.update(wrapper) > 0);
        return resp;
    }
}
